package com.qisu.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.qisu.cacheMap.ChargeQuantity;
import com.qisu.cacheMap.OrderIdCache;
import com.qisu.cacheMap.TimeAndPriceCache;
import com.qisu.dao.OrderDao;
import com.qisu.model.packet.ChargeStatusPacket;
import com.qisu.model.packet.SettlementPacket;
import com.qisu.model.vo.PayMent;

import cn.hutool.core.date.DateUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

import com.qisu.model.vo.ChargeQuantityAndPolicy;
import com.qisu.model.vo.DivisionPrice;
import com.qisu.model.vo.Gun;

/**
 * 
 * @author li
 *
 */
@Service
public class OrderService {
	@Autowired
	private OrderDao orderDao;
	@Autowired private DivisionTimeService divisionTimeService;
	@Autowired private OrderIdCache orderIdCache;
	@Autowired private ChargeQuantity chargeQuantity;
	@Autowired private TimeAndPriceCache timeAndPriceCache;
	@Value("${project.name}") private String projectName;
	private static final Log log = LogFactory.get();
	
	/**
	 * 充电中更新订单信息
	 * @param packet
	 * @param feeLoss
	 */
	public void updateOrderInfo(ChargeStatusPacket packet) {
		Map<String, Object> params = new HashMap<>(8);
		params.put("orderId", packet.getOrderId());
		params.put("voltage",packet.getDcOutputVoltage()==0 ? packet.getInputCurrentVoltage():packet.getDcOutputVoltage());
		params.put("ampere",packet.getDcOutputAmpere()==0 ? packet.getInutCurrentAmpere() : packet.getDcOutputAmpere());
		params.put("totalQuantity",packet.getChargedQualityInDegree()); 
		params.put("increaseQuantity",packet.getIncreaseQuantity());
		params.put("chargePrice",packet.getChargePrice());
		params.put("servicePrice",packet.getServicePrice());
		params.put("soc",packet.getCurrSOC());
		orderDao.updateOrderInfo(params);
		
	}

	/**
	 * 检验支付金额是否用完
	 * @param orderId
	 * @return
	 */
	public boolean hasSufficientFund(String orderId) {
		PayMent payMent = orderDao.getOrderInfo(orderId);
		if ("vip".equals(payMent.getUserType())) {
			int actualUseMoney = (int) Math.ceil((payMent.getChargeMoney()*payMent.getChargeDiscount()
					+payMent.getServiceMoney()*payMent.getServiceDiscount())/10);
			return payMent.getPayMoney() * 100 > actualUseMoney ;
		}else if ("0".equals(payMent.getUserType())) {
			int actualUseMoney = (int) Math.ceil((payMent.getChargeMoney()
					+payMent.getServiceMoney()));
			return payMent.getPayMoney() > actualUseMoney ;
		} 
		return false;
	}

	/**
	 * 根据订单ID查询桩ID和枪口号
	 * @param orderId
	 * @return
	 */
	public Gun getOrderPileAndGun(String orderId) {
		return orderDao.getOrderPileAndGun(orderId);
	}

	/**
	 * 根据订单查询的电量和资费策略
	 * @param orderId
	 * @return
	 */
	public ChargeQuantityAndPolicy getChargeQuantityAndPolicy(String orderId) {
		return orderDao.getChargeQuantityAndPolicy(orderId);
	}

	/**
	 * 根据桩枪查询电量和资费策略
	 * @param pileSerial
	 * @param gunNo
	 * @return
	 */
	private ChargeQuantityAndPolicy getChargeQuantityAndPolicyByGun(String pileSerial, int gunNo) {
		return orderDao.getChargeQuantityAndPolicyByGun(pileSerial,gunNo);
		
	}
	
	/**
	 * 查询当前时段电价与服务价格
	 * @param pileSerial
	 * @param gunNo
	 * @return
	 */
	public void getCurrentPrice(String pileSerial, int gunNo) {
		timeAndPriceCache.remove(pileSerial+gunNo);
		String orderId = orderIdCache.get(pileSerial+gunNo);
		ChargeQuantityAndPolicy chargeQuantityAndPolicy;
		if (null ==orderId) {
			 chargeQuantityAndPolicy = getChargeQuantityAndPolicyByGun(pileSerial,gunNo);
			 System.out.println(chargeQuantityAndPolicy);
			 orderIdCache.put(pileSerial+gunNo, chargeQuantityAndPolicy.getOrderId());
		}else {
			 chargeQuantityAndPolicy = getChargeQuantityAndPolicy(orderId);
		}
		log.info("当前电量 {}",chargeQuantityAndPolicy.getTotalChargeQuantity()); //电量
		log.info("当前策略 {}",chargeQuantityAndPolicy.getPolicyId());//策略id
		
		chargeQuantity.put(pileSerial+gunNo,chargeQuantityAndPolicy.getTotalChargeQuantity());
		
		//查时间与价格。
		List<DivisionPrice> divisionTimeAndPrice = divisionTimeService.getDivisionTimeAndPrice(chargeQuantityAndPolicy.getPolicyId());
		int nowTime = Integer.parseInt(DateUtil.format(new Date(), "HHmm"));
		
		for (DivisionPrice divisionPrice : divisionTimeAndPrice) {
			int startTime = divisionPrice.getDivisionStartTime();

			int endTime = divisionPrice.getDivisionEndTime();
			if (startTime < endTime ) { //不跨天的时间段
				if (nowTime < endTime && nowTime >=startTime ) { //再此时间段中
					timeAndPriceCache.put(pileSerial+gunNo, divisionPrice);//缓存当前时间与价格.
					return ;
				}
			}else { //跨天的时间段
				if (nowTime >= startTime) {//零点前
					divisionPrice.setDivisionEndTime(2400);
					timeAndPriceCache.put(pileSerial+gunNo, divisionPrice);
					return ;
				}else if (nowTime < endTime) { //零点后
					timeAndPriceCache.put(pileSerial+gunNo, divisionPrice);	
					return ;
				}
			}
		
		}
		
		if (null == timeAndPriceCache.get(pileSerial+gunNo)) {
			ArrayList<Integer> timeTemp = new ArrayList<>();
			for (DivisionPrice divisionPrice : divisionTimeAndPrice) {
				timeTemp.add(divisionPrice.getDivisionStartTime());
			}
			timeTemp.add(nowTime);
			Collections.sort(timeTemp);
			DivisionPrice divisionPrice = divisionTimeAndPrice.get(0);
			divisionPrice.setChargePrice(divisionPrice.getAvgPrice());
			if (timeTemp.get(timeTemp.size()-1)==nowTime) {
				divisionPrice.setChargePrice(divisionPrice.getAvgPrice());
				divisionPrice.setDivisionEndTime(2400);
				timeAndPriceCache.put(pileSerial+gunNo, divisionPrice);	
				return ;
			} else {
				divisionPrice.setDivisionEndTime(timeTemp.get(timeTemp.indexOf(nowTime)+1));
				timeAndPriceCache.put(pileSerial+gunNo, divisionPrice);	
				return ;
			}
		}
		
	}


	/**
	 * 停止充电更新订单信息
	 * @param packet
	 * @throws Exception 
	 */
	public void updateOrder02to03(SettlementPacket packet) throws Exception {
		orderDao.updateOrder02to03(packet);
	}

	
	
	public PayMent getOrderInfo(String orderId) {
		try {
			return orderDao.getOrderInfo(orderId);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 更新退款表
	 * @param orderId
	 * @param actualPay 
	 * @param string
	 */
	public void updateRefund(String orderId, int actualPay) {
		Map map = new HashMap<>(2);
		map.put("orderId", orderId);
		map.put("amount", actualPay);
 		orderDao.updateRefund(map);
		
	}

	/**
	 * 订单结算完成
	 * @param orderId
	 * @param actualPay
	 * @param chargeDiscountMoney
	 * @param serviceDiscountMoney
	 * @throws Exception 
	 */
	@SuppressWarnings("unchecked")
	public void updateOrder03to04(String orderId, int actualPay, int chargeDiscountMoney, int serviceDiscountMoney) {
		Map map = new HashMap<>(4);
		map.put("orderId", orderId);
		map.put("actualPay", actualPay);
		map.put("chargeDiscountMoney", chargeDiscountMoney);
		map.put("serviceDiscountMoney", serviceDiscountMoney);
		orderDao.updateOrder03to04(map);
		
	}

	public void startCharge(String orderId) {
		Map map = new HashMap<>(1);
		map.put("orderId", orderId);
		orderDao.startCharge(map);
		
	}

	public void updateRefundto2(String orderId, int actualPay) {
		Map map = new HashMap<>(2);
		map.put("orderId", orderId);
		map.put("amount", actualPay);
 		orderDao.updateRefundto2(map);
		
	}


}
